﻿/// <reference name="MicrosoftAjax.js"/>

/* 浏览器兼容层 */
//localStorage
(function () {
    var convertto = function (obj) {
        if (typeof (obj) == 'string') {
            //不进行JSON转义
            if (obj.charAt(0) == '{' || obj.charAt(0) == '*') return '*' + obj;
            return obj;
        }
        else {
            return Sys.Serialization.JavaScriptSerializer.serialize(obj);
        }
    };
    var convertfrom = function (str) {
        if (!str) return "";
        var z = str.charAt(0);
        if (z == '{' || z == '[') {
            return Sys.Serialization.JavaScriptSerializer.deserialize(str);
        }
        else if (z == '*') {
            return str.substr(1);
        }
        else {
            return str;
        }
    };
    if (!('localStorage' in window)) {
        window.localStorage = (function () {
            var documentElement, isIE = !!document.all;

            if (isIE) {
                documentElement = document.documentElement;
                documentElement.addBehavior('#default#userdata');
                return {
                    setItem: function (key, value) {
                        documentElement.setAttribute('value', value);
                        documentElement.save(key);
                    },
                    getItem: function (key) {
                        documentElement.load(key);
                        return documentElement.getAttribute('value');
                    },
                    removeItem: function (key) {
                        documentElement.removeAttribute('value');
                        documentElement.save(key);
                    }
                }
            }

            return {
                setItem: function (key, value) {
                    /// <param name="key" type="String">Cache Key</param>
                    /// <param name="value" type="Object"></param>
                    window.globalStorage[location.hostname][key] = value;
                },
                getItem: function (key) {
                    /// <param name="key" type="String">Cache Key</param>
                    return window.globalStorage[location.hostname][key];
                },
                removeItem: function (key) {
                    /// <param name="key" type="String">Cache Key</param>
                    window.globalStorage[location.hostname].removeItem(key);
                }
            };
        })();
    }
    window['localStorageEx'] = {
        setItem: function (key, value) {
            localStorage.setItem(key, convertto(value));
        },
        getItem: function (key, value) {
            return convertfrom(localStorage.getItem(key));
        },
        removeItem: function (key) {
            localStorage.removeItem(key);
        }
    }
})();
/* FF扩展 */
if (Sys.Browser.agent == Sys.Browser.Firefox) {
    HTMLElement.prototype.moveRow = function (indexFrom, indexTo) {
        if (!this.rows) return;
        var l = this.rows.length;
        if (!l) return;
        if (indexFrom == indexTo) return;
        var rFrom = this.rows[indexFrom];
        var isLast = indexTo == l;
        this.removeChild(rFrom);
        if (isLast) {
            this.appendChild(rFrom);
        }
        else {
            this.insertBefore(rFrom, this.rows[indexTo]);
        }
    }
    HTMLOptionsCollection.prototype.removeChild = function (op) {
        this.remove(op);
    }
}
/* 基础类型扩展 */
Object.createSelector = function (name) {
    return function (obj) { return obj[name]; };
}
Array.prototype.sum = function (delegate) {
    ///<summary>计算合计值，支持单个及多个值计算</summary>
    ///<param name="delegate" type="Function">选择函数</param>
    var l = this.length;
    var s = 0, i = 1, n;
    if (delegate) {
        var r = delegate(this[0]);
        if (r instanceof Object) {
            s = {};
            for (n in r) s[n] = r[n];
            while (i < l) {
                r = delegate(this[i++]);
                for (n in r) s[n] += r[n];
            }
        }
        else {
            s = r;
            while (i < l) {
                s += delegate(this[i++]);
            }
        }
        return s;
    }
    for (i = 0; i < l; i++) { s += this[i]; }
    return s;
};
Type.hasType = function (typeName, ns) {
    try {
        if (typeof (Type.parse(typeName, ns)) == 'undefined') return false;
        return true;
    }
    catch (e) {
        return false;
    }
}

Type.registerNamespace("Doo");

Doo.Utils =
{
    Cookie:
    {
        get_value: function (key) {
            /// <param name="key" type="String">Cookie Key</param>
            var allcookies = document.cookie;
            var cookie_pos = allcookies.indexOf(key);

            // 如果找到了索引，就代表cookie存在，
            // 反之，就说明不存在。
            if (cookie_pos != -1) {
                // 把cookie_pos放在值的开始，只要给值加1即可。
                cookie_pos += key.length + 1;
                var cookie_end = allcookies.indexOf(";", cookie_pos);

                if (cookie_end == -1) {
                    cookie_end = allcookies.length;
                }

                var value = unescape(allcookies.substring(cookie_pos, cookie_end));
            }

            return value;

        }
    },

    KeyValueString:
    {
        get_value: function (str, key) {///<summary>获取键值对字符串中指定key的值</summary>
            /// <param name="str" type="String">The String which get keyvalue from</param>
            /// <param name="key" type="String">Key</param>
            var find = key + "=";
            var i = 0;
            for (; ; ) {
                i = str.indexOf(find);
                if (i < 0) return null;
                if (i == 0 || str.charAt(i - 1) == '&') break;
                i = i + find.length;
            };
            var end = str.indexOf('&');
            if (end < 0) end = str.length + 1;
            return unescape(str.substring(i + find.length, end));
        }
    },

    ListAction:
    {
        singlecheck: function (elem, className) {
            /// <param name="elem" DomElement="true"></param>
            /// <param name="className" type="String">CssClass Name</param>
            if (!className) className = "checked";

            var list = elem.parentNode;
            var checkObj = list['checkObj'];
            if (!checkObj) {
                var checkIndex = list['checkindex'];
                if (checkIndex) checkObj = list.children[checkIndex];
            }

            if (checkObj == elem) return;
            if (checkObj != null) Sys.UI.DomElement.removeCssClass(checkObj, className);
            Sys.UI.DomElement.addCssClass(elem, className);

            list['checkObj'] = elem;
        },

        multicheck: function (elem, className) {
            /// <param name="elem" DomElement="true"></param>
            /// <param name="className" type="String">CssClass Name</param>
            if (!className) className = "checked";

            var hasClass = Sys.UI.DomElement.containsCssClass(elem, className);
            var cssAction = hasClass ? Sys.UI.DomElement.removeCssClass : Sys.UI.DomElement.addCssClass;
            cssAction(elem, className);
        }
    },

    Form: {
        BuildQuery: function (root) {
            ///<summary>创建查询字符串</summary>
            var nodes = root.childNodes;
            var query = {};
            for (var i = 0; i < nodes.length; i++) {
                var node = nodes[i];
                if (node.nodeType != 1) continue;
                var name = node.getAttribute('field');
                if (!name) continue;
                var value = node.value;
                if (node.control && node.control.get_code) value = node.control.get_code(); //取code
                query[name] = value;
            };
            return query;
        }
    },

    QueryString: ///<summary>查询字符串构造</summary>
    (function () {
        var Sys_QueryString = function () { };
        Sys_QueryString.prototype = {
            _query: "",
            _queryArray: {},
            toString: function (additonArgs) {
                if (!additonArgs) return this._query;
                var qa = [];
                for (var name in this._queryArray) {
                    if (name in additonArgs) {
                        qa.push(name + "=" + encodeURI(additonArgs[name]));
                        additonArgs[name] = null;
                    }
                    else {
                        qa.push(this._queryArray[name]);
                    }
                }
                for (var name in additonArgs) {
                    if (additonArgs[name] != null) {
                        qa.push(name + "=" + encodeURI(additonArgs[name]));
                    }
                }
                return "?" + qa.join("&");
            },
            add_para: function (name, value) {
                this._queryArray[name] = name + "=" + encodeURI(value);
            },
            add_paras: function (args) {
                for (var name in args) { this._queryArray[name] = name + "=" + encodeURI(args[name]); ; }
            },
            remove_para: function (name) {
                if (name in this._queryArray) { delete this._queryArray[name]; }
            },
            get_para: function (name) {
                var v = this._queryArray[name];
                if (!v) return null;
                var i = v.indexOf('=');
                return v.substr(i + 1);
            },
            set_para: function (name, value) {
                return this.add_para(name, value);
            },
            clone: function () {
                ///<summary>复制一个新对象以处理</summary>
                var newthis = new Sys_QueryString();
                newthis._query = this._query;
                newthis._queryArray = this._queryArray;
                return newthis;
            },
            init: function (query) {
                query = query != null ? query : location.search;
                this._queryArray = {};
                this._query = query;
                if (query.charAt(0) == "?") query = query.substr(1);
                if (query.length == 0) return;
                var oqs = query.split("&");
                var i = 0;
                while (i < oqs.length) {
                    var ei = oqs[i].indexOf("=");
                    if (ei >= 0) {
                        this._queryArray[oqs[i].substr(0, ei)] = oqs[i];
                    }
                    else {
                        this._queryArray[oqs[i]] = oqs[i];
                    }
                    i++;
                }
            }
        };
        var globalQ = new Sys_QueryString();
        globalQ.init();
        return globalQ;
    })(),

    Hash: {
        get_hash: function () {
            ///<summary>获取带#号的值</summary>
            var s = location.href;
            var i = s.indexOf('#');
            if (i < 0) return '';
            else return s.substr(i);
        }
    }, //Hash帮助，支持设置和获取hash值，支持对hash值监听

    Dom:
    {
        createElement: function (html, callback) {
            var temp = document.createElement('div'), frag = document.createDocumentFragment();
            temp.innerHTML = html;
            (function () {
                if (temp.firstChild) {
                    frag.appendChild(temp.firstChild);
                    setTimeout(arguments.callee, 0);
                } else {
                    callback(frag);
                }
            })();
        },
        setHtmlAsync: function (elem, html, callback) {
            /// <summary>异步设置html，提高效率</summary>
            /// <param name="elem" DomElement="true">要设置innerHTML的元素</param>
            /// <param name="html" type="String">HTML内容</param>
            /// <param name="callback" type="Function">设置成功后的回调</param>
            Doo.Utils.Dom.createElement(html, function (frag) {
                elem.innerHTML = "";
                elem.appendChild(frag);
                if (callback) callback(elem);
            });
        },
        checkTagName: function (elem, tag, scope) {
            /// <summary>检查是否是指定名字空间的指定标签</summary>
            /// <param name="tag" type="String">小写的标签</param>
            if (!elem || !elem.tagName) return false; //没有标签
            var tn = elem.tagName.toLowerCase();
            if (!scope) if (tn != tag) return false; else scope = ""; //没有名字空间且标签不对应

            var so = elem.scopeName;
            //有名字空间
            if (so) {
                return scope == so.toLowerCase(); //名字空间不对应
            }
            else {//部分浏览器是嵌入到了tagName里面
                return (scope + ':' + tag) == tn;
            }
        },
        getScopeName: function (elem) {
            /// <summary>返回小写的名字空间</summary>
            if (!elem || !elem.tagName) return null;
            if (elem.scopeName) return elem.scopeName.toLowerCase();
            var i = elem.tagName.indexOf(':');
            if (i < 0) return null;
            return elem.tagName.substring(0, i - 1).toLowerCase();
        },
        getFullTag: function (elem) {
            ///<summary>返回完整的标签</summary>
            if (elem.scopeName) return (elem.scopeName + ':' + (elem.localName || elem.tagName)).toLowerCase();
            else return elem.tagName.toLowerCase();
        }
    },

    eval: function (context, statments) {
        with (context) {
            return eval(statments);
        }
    }
};
Doo.Utils.Ajax = (function () {
    var defaultSite = null;
    var randp = function () { return new Date().setFullYear(1991); };
    var _frameParent = null;
    var timeoutstatus = 504;
    var _createUCFrame = function (p) {
        if (_frameParent == null) {
            _frameParent = document.createElement("div");
            document.body.insertBefore(_frameParent, document.body.firstChild);
        };
        var ifmid = 'UC_FRAME' + (p || '');
        var ifm = window[ifmid];
        if (!ifm) {
            ifm = document.createElement("iframe");
            ifm.style.width = 0;
            ifm.style.height = 0;
            ifm.frameBorder = 0;
            _frameParent.appendChild(ifm);
            window[ifmid] = ifm;
        }
        return ifm;
    };
    var _destoryUCFrame = function (p) {
        var ifmid = 'UC_FRAME' + (p || '');
        var ifm = window[ifmid];
        if (ifm) {
            ifm.parentNode.removeChild(ifm);
            window[ifmid] = null;
        }
    };
    var _crossAjax = function (args) {
        ///<summary>跨域获取数据</summary>
        ///<param name="args">参数，包括uniqueid,url,params,method,onsucc,onfail,callbackname,timeup</param>
        var uniqueid = args.uniqueid || randp();
        var ifm = _createUCFrame(uniqueid);
        if (ifm['onsucc']) return;

        var callbackname = args.callbackname || ("crosscallback" + uniqueid);
        var method = args.method || 'post';

        var parambuilder = [];
        var p = args.params;
        var u = args.url;
        var host = location.host;
        var ui = u.indexOf('?');

        if (method == 'get') {

            //处理get参数
            if (!p) p = { host: host, callbackname: callbackname };
            else if (!p.host) { p.host = host; p.callbackname = callbackname; }
            if (ui > 0) {
                var ps = u.substring(ui + 1).split('&');
                if (ps && ps.length > 0) {
                    for (var i = 0; i < ps.length; i++) {
                        var j = ps[i].indexOf('=');
                        p[ps[i].substring(0, j)] = ps[i].substring(j + 1);
                    }
                }
            }
        }
        else {//post
            u += (ui >= 0 ? '&' : '?') + 'host=' + host + '&callbackname=' + callbackname;
        }
        if (p) {
            for (var n in p) {
                parambuilder.push(String.format("<input type='text' name='{0}' value='{1}'/>", n, p[n]));
            }
        }

        var doc = ifm.contentWindow.document;
        doc.open();
        doc.write("<html><head></head><body><form method='" + method + "' action='" + u + "'>" +
		parambuilder.join('') +
		"<button type='submit'></button></form></body></html>");
        doc.close();

        var timeout = (args.timeout || 10) * 1000;
        var onfail = args.onfail;
        var onsucc = args.onsucc;
        var persist = args.persist;

        var failTimer = setTimeout(function () {
            if (onfail) { onfail(timeoutstatus); }
            _destoryUCFrame(uniqueid);
        }, timeout);
        var succFunc = function () {
            clearTimeout(failTimer);
            if (onsucc) { onsucc.apply(window, arguments); }
            if (!persist) _destoryUCFrame(uniqueid);
        }
        window[callbackname] = succFunc;

        doc.forms[0].submit();
        return uniqueid;
    };

    var _clearAjax = function (id) {
        //清除id对应的，如果有的话
        _destoryUCFrame(id);
    };

    return {
        set_defaultSite: function (v) {
            defaultSite = v;
        },
        get_defaultSite: function () {
            return defaultSite;
        },
        istimeout: function (s) { return s == timeoutstatus; },
        crossAjax: _crossAjax,
        clearAjax: _clearAjax
    };
})();



Doo.Delegate = function (func, obj) {
    /// <param name="func" type="Function"></param>
    /// <param name="obj" type="Object">The Object This Point Reference To</param>
    return function () { return func.apply(obj, arguments); };
}

/* 增加css样式 */
Doo.Css = {
    _imported: {},
    getSheet: function () {
        var sss = document.styleSheets;
        if (sss.length == 0) {
            var elem = document.createElement("style");
            elem.type = "text/css";
            document.body.appendChild(elem);
        }
        var sheet = sss[0];
        return sheet.sheet || sheet; //兼容部分浏览器
    },
    importCss: function (url) {
        if (this._imported[url]) return;

        this.getSheet().addImport(url);
        this._imported[url] = true;
    },
    addCssRule: function (selector, cssText) {
        ///<summary>设置CSS规则</summary>
        ///<param name="selector" type="String">选择符</param>
        ///<param name="cssText" type="String">要设置的规则</param>
        ///<returns>FF下返回新规则的序号</returns>
        var sheet = this.getSheet();
        var rules = sheet.cssRules || sheet.rules;
        var r = rules[selector];
        return sheet.addRule ? sheet.addRule(selector, cssText) : sheet.insertRule(selector + '{' + cssText + '}', sheet.cssRules.length);
    }
};
Doo.Resources = {
    RegCss: function (key, path) {
        /// <param name="key" type="String"></param>
        /// <param name="path" type="String"></param>
        var cssid = "Doo_CSS_" + key;
        if ($get(cssid)) return;
        var elem = document.createElement("link");
        elem.type = "text/css";
        elem.rel = "stylesheet";
        elem.src = path;
        document.body.appendChild(elem);
    }
}

Doo.Scripts =
{
    SetEvents: function (obj, events) {
        /// <param name="obj" type="Object">object which set events on</param>
        /// <param name="events" type="Object">a hasharray</param>
        /// <summary>设置事件，注意，对象必须在Sys.load事件之前拥有__handlerList属性</summary>
        // 对象中只有一个__handlerList，对于Control来说，就是ControlBase.prototype.__handlerList
        // if (!obj['__handlerList']) obj['__handlerList'] = new Sys.EventHandlerList();
        if (events instanceof Array) {
            Array.forEach(events, function (name) { this._SetEventItem(obj, name); }, this);
        }
        else {
            for (var name in events) {
                this._SetEventItem(obj, name, events[name]);
            }
        }
    },
    _SetEventItem: function (obj, name, handlers) {
        if (!obj['add_' + name]) {
            //此处用this指针的__handlerList，每个对象的事件相互隔离
            obj['add_' + name] = function (handler) { this.__handlerList.addHandler(name, handler); };
            obj['remove_' + name] = function (handler) { this.__handlerList.removeHandler(name, handler); };
            obj['on' + name] = function () { var h = this.__handlerList.getHandler(name); if (h != null) h.apply(this, arguments); };
        }
        if (Array.isInstanceOfType(handlers)) {
            //注册，使init时再转换events
            this.eventinits.push(function () { Doo.Scripts.InitObjEvents(obj, name, handlers); });
        };
    },
    InitObjEvents: function (obj, name, handlers) {
        var scripts = obj.get_scripts() || window;
        var ____hh;
        var events = obj['__handlerList'];
        for (var __doo__i = 0; __doo__i < handlers.length; __doo__i++) {
            ____hh = Doo.Utils.eval(scripts, handlers[__doo__i]);
            events.addHandler(name, ____hh);
        }
    },

    SetFuns: function (obj, functions) {
        for (var name in functions) {
            obj[name] = Doo.Delegate(functions[name], obj);
        }
    },

    _createDomToAttach: function (id) {
        var d = this['__d'];
        if (!d) {
            d = document.createElement("div");
            document.body.insertBefore(d, document.body.firstChild);
            this['__d'] = d;
        }
        var i;
        try {
            i = document.createElement("<div id='" + id + "'>");
        } catch (e) {
            i = document.createElement("div");
            i.id = id;
        }

        d.appendChild(i);
        return i;
    },

    InitObj: function (name, fields, events, functions, typename, init, id, parentname) {
        var obj, type;
        if (typename && typename != 0) {
            try {
                type = Type.parse(typename);
            }
            catch (e) {
                throw new Error(typename + "类型未能加载，检查脚本是否引用");
            }
            if (!type.inheritsFrom(Doo.ControlBase)) {
                throw new Error(typename + "类型没有继承Doo.ControlBase");
            }
        }
        else {
            type = Doo.ControlBase;
        }
        obj = $create(type, null, null, null, this._createDomToAttach(name));
        if (fields != null) {
            for (var n in fields) {
                obj[n] = fields[n];
            }
        }

        obj['__id'] = name;
        if (id) {
            obj.ctlid = id;
            obj.scriptsid = parentname;
            Doo.Scripts.add_init(function () { window[parentname].addChild(obj); });
        }
        if (events != null) {
            obj['__handlerList'] = new Sys.EventHandlerList();
            this.SetEvents(obj, events);
        }
        if (functions) this.SetFuns(obj, functions);
        if (init.length > 0) {
            Doo.Scripts.add_init(obj[init]);
        }

        window[name] = obj;
    },

    eventinits: new Array(),

    load_handler: function () { Doo.Scripts.init_complete(); },
    inits: new Array(),
    add_init: function (handler) {
        this.inits.push(handler);
    },
    init_complete: function () {
        //事件初始化

        if (this.eventinits) {
            for (var ei = 0; ei < this.eventinits.length; ei++) {
                this.eventinits[ei]();
            }
            this.eventinits = null;
        }

        for (var ii = 0; ii < this.inits.length; ii++) {
            this.inits[ii]();
        }
        this.inits.length = 0;
    }
}
Sys.Application.add_load(Doo.Scripts.load_handler); //在所有init后执行

Doo.Caching = {
    DataVersionManager:
    {
        init: function () {
            //在页面初始化时执行，对pageversion进行处理
            if (!window['pagever']) return;
            //将pagever加入到缓存中
            var pv = window['pagever'];
            for (var n in pv) {
                var ov = localStorage.getItem(n);
                if (pv[n] < ov) localStorage.setItem(n, pv[n]);
            };
            this.versions = pv;
        },
        versions: null,
        refresh: function () {//刷新
            var vs = this.versions;
            if (!vs) return;
            for (var n in vs) {
                vs[n] = localStorage.getItem(n);
            };
            if (frameElement && frameElement.window && frameElement.window.Doo) {
                frameElement.window.Doo.Caching.DataVersionManager.refresh();
            }
        },
        get_version: function (k) {
            if (this.versions) {
                return this.versions[k];
            }
        }
    }
}
Doo.Caching.DataVersionManager.init(); //初始化版本数据库

Doo.Behavior = {
    "watermark": (function () {
        ///<summary>水印文本框</summary>
        var watermark_css = "watermark",
    watermark_focus = function () {
        var a = this;
        if (a['watering']) {
            a.value = '';
            Sys.UI.DomElement.removeCssClass(a, watermark_css);
        }
    },
        watermark_blur = function () {
            var a = this;
            if (a.value == '') {
                a['watering'] = true;
                Sys.UI.DomElement.addCssClass(a, watermark_css);
                a.value = a['watertxt'];
            }
            else {
                a['watering'] = false;
            }
        },
        makeWaterMark = function (txtbox, watertxt) {
            if (txtbox['beh_watermark']) return;
            txtbox['beh_watermark'] = true;
            txtbox['watertxt'] = watertxt.watertxt || watertxt; //可能传入一个对象或字符串
            $addHandler(txtbox, "focus", watermark_focus);
            $addHandler(txtbox, "blur", watermark_blur);

            var og = txtbox.get_value;
            txtbox.get_value = function () {
                var v = og ? og(this) : this.value;
                if (this['watering'] == true) return '';
                else return v;
            };

            watermark_blur.call(txtbox);
        };
        return makeWaterMark;
    })()
}

Doo.ControlBase = function (element) {
    Doo.ControlBase.initializeBase(this, [element]);
}

Doo.ControlBase.Items =
{
    length: 0,
    controls: {},
    add: function (control) {
        control.index = this.length;
        this.controls[this.length++] = control;
    },
    remove: function (control) {
        this.controls[control.index] = null;
    },
    get: function (index) {
        return this.controls[index];
    }
}

var $items = Doo.ControlBase.Items;

Doo.ControlBase.prototype = {
    initialize: function () {
        Doo.ControlBase.callBaseMethod(this, 'initialize');

        this['__handlerList'] = new Sys.EventHandlerList();
        Doo.ControlBase.Items.add(this);

        Doo.Scripts.SetEvents(this, this.initevents);
        this.childs = [];
        this.namedchilds = {};
        // 如果有父级，则添加自己
        var so = this.get_scripts();
        if (so && so.addChild) {
            so.addChild(this);
        }

    },
    dispose: function () {
        //Add custom dispose actions here
        Doo.ControlBase.Items.remove(this);
        //处理子控件
        this.clearChilds();
        this._asyncver = -1;

        Doo.ControlBase.callBaseMethod(this, 'dispose');
    },

    _loaded: false,

    load: function () {
        ///<summary>在派生类重写时，处理load的内容。当所在容器中所有控件完成initialize时即触发load</summary>
        if (this.childs && this.childs.length > 0) {
            Array.forEach(this.childs, function (c) { if (c.load) c.load(); });
        }
        this._loaded = true;
    },

    __handlerList: null,

    __validators: null,
    isValid: function () {
        ///<summary>是否已通过验证</summary>
        if (this.__validators instanceof Array) {//如果有验证器
            return false;
        }
        else {//没有验证器就直接返回false
            return true;
        }
    },

    __dataitem: 0,
    set___dataitem: function (v) { this.__dataitem = v; },
    get___dataitem: function () { return this.__dataitem; },

    index: null,

    ctlid: null,

    scriptsid: null, //所依附的脚本对象，将作为其子对象
    __scope: null, //域
    get_scripts: function () {
        ///<returns type="Doo.ControlBase">返回脚本对象<returns>
        var i = this.scriptsid;
        return i == null ? this.__scope : window[i];
    },

    initevents: {},
    set_initevents: function (evts) {
        this.initevents = evts;
    },
    get_initevents: function () {
        return this.initevents;
    },

    call_event: function (name, args) {
        this.get_scripts()[name](this, args);
    },

    //子控件，用数组是因为没有id的用push方法
    childs: null,
    namedchilds: null,

    _childLock: 0,

    isChildsReady: function () {
        return this._childLock == 0;
    },

    beginCreateChilds: function () {
        this._childLock++;
    },

    endCreateChilds: function () {
        this._childLock--;
        if (this._childLock == 0) {
            this.onChildsReady(this);
        }
    },

    findChild: function (ctlid) {
        return this.namedchilds[ctlid];
    },
    addChild: function (ctl) {
        ///<param name="ctl" type="Sys.UI.Control"></param>
        if (ctl == this) {
            throw new Error("循环错误");
        }
        if (ctl.ctlid) {
            this.namedchilds[ctl.ctlid] = ctl;
        }
        var _this = this;
        this.childs.push(ctl);
        this.onChildAdded(ctl);
    },
    clearChilds: function () {
        var cs = this.childs;
        for (var i = 0; i < cs.length; i++) {
            if (cs[i] && cs[i].dispose) cs[i].dispose();
        }

        this.childs.length = 0;
        this.namedchilds = {};
    },

    _asyncver: 0, //同步版本，避免出错

    newAsync: function () {
        ///<summary>创建新同步版本号</summary>
        return ++this._asyncver;
    },

    get_asyncver: function () {
        ///<summary>获取当前同步版本号</summary>

        return this._asyncver;
    },

    checkAsync: function (v) {
        ///<summary>检查同步版本号</summary>
        return !(v != this._asyncver || v < 0);
    },
    tplevents: null, //事件定义
    get_tplevents: function () {
        /// <returns type="Array"></returns> 
        return this.tplevents;
    },
    set_tplevents: function (es) {
        ///<summary>设置模版事件</summary>
        this.tplevents = es;
    },
    init_tplevents: function (es) {
        ///<summary>用字符串形式初始化模版事件集</summary>
        var context = this.get_scripts() || window;

        for (var __doo__i in es) {
            if (es[__doo__i].length) {
                es[__doo__i] = Doo.Utils.eval(context, es[__doo__i]);
            }
        }
        this.tplevents = es;
    },
    set_inittplevents: function (es) {
        this.init_tplevents(es);
    },
    get_inittplevents: function () {
        return null;
    },
    init_tplevent: function (name, evtstr) {
        var s = {};
        s[name] = evtstr;
        this.init_tplevents(s);
    },
    get_tplevent: function (name) {
        if (!this.tplevents) return null;
        return this.tplevents[name];
    },
    set_tplevent: function (name, evt) {
        if (!this.tplevents) this.tplevents = {};
        this.tplevents[name] = evt;
    },

    tpleventargs: null, //事件参数

    trig_tplevent: function (event, argindex, elem) {
        var args = this.tpleventargs[argindex];
        var handler = this.get_tplevent(args[0]);
        if (typeof (handler) == 'string') handler = eval(handler);
        if (!event) event = window.event;
        var evt = event == null ? null : new Sys.UI.DomEvent(event); //如果是a标签的href引发的事件则取不到event值
        handler(this, args, elem, evt);
    },

    getBindData: function (deep) {
        ///<summary>获取绑定数据</summary>
        ///<param name="deep">是否深层获取</param>
        //遍历子控件，目前只遍历当前子控件。
        var oldData = {}, newData = {};
        var nc = this.namedchilds;
        for (var i in nc) {
            var c = nc[i];
            var bindings = c['__bindings'];
            if (!bindings || bindings == {}) continue;
            for (var n in bindings) {
                var d = bindings[n];
                var dp = d[0];
                var getfun = c['get_' + n];
                var nv = getfun ? getfun.call(c) : c[n];
                oldData[dp] = d[1];
                newData[dp] = nv;
            }
        }
        return { olddata: oldData, newdata: newData };
    }
}

Doo.Scripts.SetEvents(Doo.ControlBase.prototype, { "ChildsReady": 0, "ChildAdded": 0 });
Doo.ControlBase.registerClass('Doo.ControlBase', Sys.UI.Control);

Doo._CreatePageControls = function (ctlidArray) {
    ///<summary>由框架调用，创建页面上的控件</summary>
    if (!window.$Page) $Page = $create(Doo.ControlBase, null, null, null, document.body);
    var callback = function (ctl) {
        $Page.addChild(ctl);
    };
    for (var i = 0; i < ctlidArray.length; i++) {
        $ctl(ctlidArray[i], callback, null, null, $Page);
    }
}

Doo.ControlScripts = {};

Doo.ControlTag = {
    ///<summary>标签注册，格式scopename-namespace</summary>
    "doo": ["Doo",
        {
            "listview": "ListView",
            "gridview": "GridView",
            "pager": "Pager",
            "objdatasource": "DataSource.ObjDataSource"
        }]
}

Doo.ControlLoader = {
    scriptLoaded: function (sender, context, _errcount) {
        var controltype = context["type"];
        var type, typeLoaded = 1;
        var checkTypes = context["checkTypes"];
        for (var i = checkTypes.length - 1; i >= 0; i--) {
            var ct = checkTypes[i];
            if (!Type.hasType(ct)) {
                typeLoaded = 0;
                break;
            }
        }
        if (typeLoaded == 1) {
            try {
                type = Type.parse(controltype);
                if (typeof (type) == 'undefined') {
                    typeLoaded = 0;
                }
            }
            catch (e) {
                typeLoaded = 0;
            }
        }

        if (typeLoaded == 0) {
            _errcount = (_errcount || 0) + 1;
            if (_errcount > 20)
                throw new Error(controltype + "类型无法加载");
            else {
                setTimeout(function () { Doo.ControlLoader.scriptLoaded(sender, context, _errcount); }, _errcount * 10);
                return;
            }
        }
        Sys.Debug.trace("类型已加载[脚本加载器]:" + controltype);
        var path = context["url"];
        if (path) {
            var li = path.lastIndexOf('/');
            type.prototype['path'] = path.substring(0, li + 1); //所有这一类型的控件路径均为这个
        }
        Doo.ControlLoader.loadedType[controltype] = 1; //此时该类型才加载完成[成功赋值path]

        //遍历要创建的控件数组
        var cs = Doo.ControlLoader.waitTypeControl[controltype];
        for (var i = 0; i < cs.length; i++) {
            var ctx = cs[i];
            var elem = ctx[0];
            var props = ctx[2] || {};
            var asyncV = ctx[4];
            var asyncSrc = ctx[5];
            if (asyncSrc && !asyncSrc.checkAsync(asyncV)) return; //同步版本号校验失败
            var callback = ctx[3];
            var control = $create(type, props, null, null, elem);
            control['__scope'] = asyncSrc;
            Doo.ControlLoader.controlCreated(elem, control);
            Sys.Debug.trace("控件已加载[脚本加载器]:" + control._element.id);

            if (callback) callback(control, ctx[6]);
        }

        delete Doo.ControlLoader.waitTypeControl[controltype];
    },

    loadedType: {}, //加载类型
    waitTypeControl: {}, //类型加载完成后要创建的控件

    resources: null,
    _path2version: null,
    _initres: function (res, array, path) {
        for (var n in res) {
            var v = res[n];
            if (v instanceof Function) {
                continue;
            }
            else if (v instanceof Array) {
                array[v[0]] = [path + n, v[1]]; //path,version
            }
            else {
                this._initres(v, array, path + n + '/');
            }
        }
    },
    initResources: function (res) {
        ///<summary>注册资源</summary>
        var r = new Array();
        var path = '/';
        this._initres(res, r, path);
        var p2v = [];
        for (var i = 1; i < r.length; i++) {//resIndex从1开始
            p2v[r[i][0]] = r[i][1];
        };
        this._path2version = p2v;
        this.resources = r;
    },
    getResourcePath: function (i) {
        var v = this.resources[i][1];
        return this.resources[i][0] + (v == 0 ? "" : "?t=" + v);
    },
    getVersionByPath: function (p) {
        return this._path2version[p];
    },

    dependServices: {}, //依赖的web服务。格式为resourceIndex:[type,loaded]。loaded为0时为未判断，1时为正在加载，2时为已加载
    initDependServices: function (services, ns) {
        ///<summary>初始化依赖服务</summary>
        ///<param type="Object" name="services">服务，格式为{name:[index,type]}</param>
        var ds = {};
        //附加名字空间和路径
        for (var n in services) {
            var s = services[n];
            //s[0] = this.getResourcePath(s[0]);//还是使用index
            if (ns != '') s[1] = ns + '.' + s[1];
            ds[s[0]] = [s[1]];
        }

        this.dependServices = ds;
    },

    dependFiles: {}, //依赖的文件，格式为 控件类型:依赖资源序号
    initDependFiles: function () {
        ///<summary>初始化依赖文件</summary>
    },

    controlDependServices: {}, //控件依赖的web服务

    initControlDefs: function (defs, ns, tagPrefix) {
        ///<summary>初始化控件定义</summary>
        ///<param type="Array" name="services">控件数组，格式为name:[scriptres,scripttype,dependservices,dependfiles]</param>
        var tags = {};
        for (var n in defs) {
            var def = defs[n];
            //2011.1.18新修改：[resIndex,dependIndex,typename,tagname]，如果后两者为空，则使用n
            var resIndex = def[0], tagname, typename, dependServices;
            if (def.length < 2) {
                tagname = typename = n;
            }
            else if (def[1] instanceof Array) {//新版顺序
                dependServices = def[1];
                tagname = typename = n;
            }
            else {
                dependServices = def[3];
                typename = def[1] || n;
                tagname = def[2] || typename;
            };
            Doo.ControlScripts[ns + '.' + typename] = this.getResourcePath(resIndex);
            var taglni = n.lastIndexOf('.');
            tags[(taglni > 0 ? (n.substr(taglni + 1)) : n).toLowerCase()] = tagname;
            if (dependServices instanceof Array) {
                this.controlDependServices[ns + '.' + typename] = dependServices;
            }
        };
        Doo.ControlTag[tagPrefix.toLowerCase()] = [ns, tags];
    },

    createChilds: function (nodes, ctl, locker) {
        ///<summary>在给定的节点数组上递归扫描并创建控件</summary>
        ///<param name="nodes" type="Array">Html节点数组</param>
        ///<param name="ctl" type="Doo.ControlBase">Doo控件</param>
        ///<param name="locker" type="Doo.TemplateBinder">可锁定的量</param>
        var i = 0, canadd = ctl.addChild;
        if (locker) locker.beginLock();

        while (i < nodes.length) {
            var n = nodes[i], ctlid = 0;

            if (n.tagName && (ctlid = n.getAttribute("ctlid"))) {
                if ((n.scopeName && n.scopeName.toLowerCase() != 'html') || n.tagName.indexOf(':') > 0) {
                    //是ctl
                    if (locker) locker.beginLock();
                    $ctl(n, function (c, cid) {
                        c.ctlid = cid;
                        if (canadd) ctl.addChild(c);
                        if (locker) locker.endLock();
                    }, null, {}, ctl, ctlid);

                }
                else {
                    //是dom
                    n.__scope = ctl;
                    Doo.ControlLoader.controlCreated(n, n);
                    if (canadd) ctl.addChild(n);

                    if (!n.getAttribute("stopctl") && n.childNodes && n.childNodes.length) {
                        arguments.callee(n.childNodes, ctl, locker);
                    }
                }
            }
            else {
                if (n.childNodes) arguments.callee(n.childNodes, ctl, locker);
            }
            i++;

        }
        if (locker) locker.endLock();
    },

    controlCreated: function (elem, control) {
        ///<summary>当控件或Html元素创建完成后调用</summary>
        var getvalue = function (str, elem) {
            ///<summary>转换字符串</summary>
            if (str.length < 2) return str;
            var c0 = str.charAt(0), c1 = str.charAt(1);
            if (c0 == '%') {
                var t = str.substr(1);
                return c1 != '%' ? eval(t) : t;
            }
            else if (c0 == '$') {
                if (c1 == 'i') {//返回子集文本
                    return elem.innerHTML;
                }
                else if (c1 == 'c') {//返回被注释包围的文本
                    var t = elem.innerHTML.trim();
                    if (t.startsWith("<!--") && t.endsWith("-->")) {
                        return t.substring(4, t.length - 3);
                    }
                    throw new Error("没有找到有效的注释区块");
                }
                else if (c1 == 'r' && str.charAt(2) == '-') {//返回引用的控件（同级）[TODO:由于异步加载的特殊性，可能引用到的控件会出现错误，应给予改进，在所有控件创建完成之后再行处理]
                    var scope = control.__scope;
                    return scope == null ? null : scope.findChild(str.substr(2));
                }
                else if (c1 == 'p' && str.charAt(2) == '-') {
                    return Doo.Utils.QueryString.get_para(str.substr(3));
                }
                else if (c1 == "o" || c1 == "a") {//构造对象或数组并返回
                    var isobject = c1 == 'o';
                    var retobj = isobject ? {} : [];
                    var pe = elem.firstChild;
                    while (pe) {
                        if (pe.tagName && Doo.Utils.Dom.getFullTag(pe) == 'doo:prop') {
                            retobj[isobject ? pe.getAttribute("name") : retobj.length] = getvalue(pe.getAttribute("value"), pe);
                        }
                        pe = pe.nextSibling;
                    }
                    return retobj;
                }
            }
            return str;

        }
        var process = function (attrs, elem) {
            var srcattrs = []; //由于原始集合可能会改变，所以需要记录原始集合 2010.11.22
            for (var i = 0; i < attrs.length; i++) {
                var a = attrs[i].name;
                var ti = a.indexOf(':');
                if (ti < 0) continue;
                srcattrs.push([a.substring(0, ti), a.substr(ti + 1), getvalue(attrs[i].value, elem)]);
            }
            for (var i = 0; i < srcattrs.length; i++) {
                var a = srcattrs[i];
                var loader = this.attrLoader[a[0]];
                if (!loader) continue;
                loader.call(this.attrLoader, control, a[1], a[2]); //TODO:处理表达式
            }
        };

        process.call(this, elem.attributes, elem);
        var fs = elem.firstChild;
        while (fs) {
            if (!fs.tagName) {
                fs = fs.nextSibling;
                continue;
            }
            var tn = Doo.Utils.Dom.getFullTag(fs);
            if (tn == "doo:mp") {
                process.call(this, fs.attributes, fs);
            }
            else if (tn == "doo:doex") {
                //doex--调用多个方法
                var methodname = fs.getAttribute("method");
                if (!methodname) throw new Error("未指定方法名");
                var para = [];
                for (var i = 1; i < 10; i++) {//支持直接写9个参数
                    var p = fs.getAttribute("para" + i);
                    if (!p) break;
                    para.push(getvalue(p, fs));
                }

                var pe = fs.firstChild;
                while (pe) {
                    if (pe.tagName && Doo.Utils.Dom.getFullTag(pe) == 'doo:para') {
                        para.push(getvalue(pe.getAttribute("value"), pe));
                    }
                    pe = pe.nextSibling;
                }
                var func = control[methodname];
                if (!func) { throw new Error(methodname + "不是此时创建的控件的一个方法"); }
                func.apply(control, para);
            }
            else if (tn == "doo:bhv") {
                //bh--创建行为
                var type = fs.getAttribute("type");
                if (!type) throw new Error("未指定类型名");
                var para = {};
                var attrs = fs.attributes;
                for (var i = 0; i < attrs.length; i++) {
                    var attit = attrs[i];
                    if (!attit.specified) continue;
                    var attname = attit.nodeName;
                    if (attname == 'type') continue;
                    para[attname] = attit.nodeValue;
                }
                var bhcreator = Doo.Behavior[type];
                bhcreator(control, para);
            }
            else {
                break;
            }
            var ns = fs.nextSibling;
            elem.removeChild(fs);
            fs = ns;
        }
    },

    attrLoader: {
        ///<summary>属性加载器。一个使用加载器的典型属性为set:title="my title"其中set为属性加载器名，title为名字，等号后的内容是要加载的内容。</summary>
        ///调用时，this指向ControlLoader
        ///Doo2.0版不做编译操作，可能在3.0版中引入编译。
        ///传递的参数中value是经过表达式处理后的值
        "set": function (obj, name, value) {
            ///<summary>为对象赋值</summary>
            var setfun = obj['set_' + name];
            if (setfun) {
                setfun.call(obj, value);
            }
            else {
                //针对文本框做特殊处理
                if (name == 'value' && Sys.UI.DomElement.isDomElement(obj) && (value == null || typeof value == undefined)) {
                    value = '';
                };
                obj[name] = value;
            }
        },
        "do": function (obj, name, value) {
            ///<summary>调用对象方法</summary>
            var dofun = obj[name];
            if (typeof (dofun) !== 'function') throw new Error(name + "不是一个有效的方法");
            dofun.call(obj, value);
        },
        "bhv": function (obj, name, value) {
            ///<summary>附加行为，name是行为名字，value是方法</summary>
            var bhv = Doo.Behavior[name];
            bhv(obj, value);
        },
        "evt": function (obj, name, value) {
            ///<summary>为对象事件增加句柄</summary>
            var context = obj.__scope || (obj.get_scripts && obj.get_scripts()) || window,
            handler = context[value] || Doo.Utils.eval(context, value);
            if (!handler) throw new Error(value + "不是一个有效的句柄");

            if (Sys.UI.DomElement.isDomElement(obj)) {
                var delegate = function (evt) {
                    var domevt = new Sys.UI.DomEvent(evt || window.event);
                    handler.call(context, this, domevt); //参数：sender,evt
                };
                $addHandler(obj, name, delegate);
            }
            else {
                var addfun = obj['add_' + name];
                if (typeof (addfun) !== 'function') throw new Error(name + "不是一个有效的事件");
                //value是字符串，此处需要转成handler
                addfun.call(obj, Function.createDelegate(context, handler));
            }
        },
        "nevt": function (obj, name, value) {
            ///<summary>为对象事件增加句柄</summary>
            var context = obj.__scope || (obj.get_scripts && obj.get_scripts()) || window,
            handler = context[value] || Doo.Utils.eval(context, value);
            if (!handler) throw new Error(value + "不是一个有效的句柄");

            if (Sys.UI.DomElement.isDomElement(obj)) {
                var delegate = function (evt) {
                    var domevt = new Sys.UI.DomEvent(evt || window.event);
                    handler.call(context, this, domevt); //参数：sender,evt
                };
                $addHandler(obj, name, delegate);
            }
            else {
                obj[name] = function () {
                    handler.apply(context, arguments);
                };

            };
        },
        "tplevt": function (obj, name, value) {
            ///<summary>为对象模板事件增加句柄</summary>
            //value是字符串，此处需要转成handler
            var context = obj.get_scripts() || window;
            var handler;
            handler = Doo.Utils.eval(context, value);
            if (!handler) throw new Error(value + "不是一个有效的句柄");
            obj.set_tplevent(name, Function.createDelegate(context, handler));
        },
        ///以下只对具有数据项有效

        bindHelper: function (obj, objprop, dataprop, saveoldvalue) {
            ///<summary>绑定帮助器</summary>
            ///<param name="saveoldvalue">是否保存旧值</param>
            var bindings = obj['__bindings'];
            if (!bindings) bindings = obj['__bindings'] = {};
            var oldvalue = undefined;
            if (saveoldvalue) {
                var getfun = obj['get_' + objprop];
                if (getfun) oldvalue = getfun.call(obj);
                else oldvalue = obj[objprop];
            }
            bindings[objprop] = [dataprop, oldvalue];
        },

        'bind': function (obj, name, value) {
            ///<summary>双向绑定</summary>
            this.lbind(obj, name, value);
            this.bindHelper(obj, name, value, true);
        },
        'lbind': function (obj, name, value) {
            ///<summary>单向绑定：数据->属性</summary>
            var dataitem = obj['__dataitem'];
            if (dataitem) {
                this.set(obj, name, dataitem[value]);
            }
        },
        'rbind': function (obj, name, value) {
            ///<summary>单向绑定：属性->数据</summary>
            ///用途：可用于新增数据时，用set赋初始值，bindR将值写入数据
            ///或用于编辑数据时，用set[支持表达式，如空转换，直接用bind会出现空字符串。可用于日期等需要默认值的地方]将数据写入值，用bindR将值写回
            this.bindHelper(obj, name, value, false);
        }
    }
}

$ctl = function (elemorid, callback, controltype, props, asyncSrc, userContext) {
    ///<summary>使用Doo语法从一个Dom元素创建一个控件（延迟创建特性）</summary>
    ///<param name="elemorid" type="String">依附的元素ID或直接传入元素</param>
    ///<param name="callback" type="Function">成功创建元素后的回调，callback(control)</param>
    ///<param name="controltype" type="String">[可选]在代码中指定控件的类型，如果为空，将从Dom的TagName中寻找类型</param>
    ///<param name="props" type="Object">[可选]Json值，将会覆盖元素的ctl\:prop属性中相同属性</param>
    ///<param name="asyncSrc" type="Doo.ControlBase">[可选]同步源，如果过程中同步版本变化，则中断后续操作，将不再创建控件和回调</param>
    ///<remarks>支持多种语法，内置语法有：赋值类：set，绑定类：bind,bindL,bindR，事件类：evt，方法类：do</remarks>
    if (String.isInstanceOfType(elemorid)) {
        elemorid = $get(elemorid);
    }
    Sys.Debug.trace("创建控件" + elemorid.id);
    if (!elemorid) throw new Error("错误的元素在$control调用");
    if (elemorid.control) {
        throw new Error("已经有一个控件了");
    }
    if (!controltype) {
        var tn;
        var so = elemorid.scopeName;
        if (so) { so = so.toLowerCase(); tn = (elemorid.localName || elemorid.nodeName).toLowerCase(); }
        else {//说明浏览器的scopeName没有值，需要从tagName中取
            tn = elemorid.tagName.toLowerCase();
            var si = tn.indexOf(':');
            so = tn.substring(0, si);
            if (!so) throw new Error("没有找到控件类型");
            tn = tn.substr(si + 1);
        }
        var ns = Doo.ControlTag[so];
        if (ns[1][tn]) tn = ns[1][tn];
        controltype = ns[0] + "." + tn;
    }

    //查找并加载依赖项
    var needLoadScriptUrls = []; //需要加载的脚本
    var needCheckTypes = []; //需要检查的类型[以确信真的加载成功了]
    var needWait = false; //需要等待加载
    var scriptUrl;

    //1.加载web服务
    var dependServices = Doo.ControlLoader.controlDependServices[controltype];
    if (dependServices instanceof Array) {
        for (var i = dependServices.length - 1; i >= 0; i--) {//每一个项目分为：
            var serviceIndex = dependServices[i];
            var service = Doo.ControlLoader.dependServices[serviceIndex];
            if (!service || service[1] == 1) continue; //已加载
            else if (service[1] == 0) {
                needWait = true;
                continue;
            }
            var serviceType = service[0];
            if (Type.hasType(serviceType)) continue;
            needLoadScriptUrls.push(Doo.ControlLoader.getResourcePath(serviceIndex));
            needCheckTypes.push(serviceType);
        }
    }

    //2.加载控件脚本
    var typeLoadingStatus = Doo.ControlLoader.loadedType[controltype] || 2; //没有出现的应该假设为已加载
    if (typeLoadingStatus != 0) {//必须的，避免js加载完成，可以解析type，但还没有执行scriptloaded赋值path
        try {
            var type = Type.parse(controltype);
            if (typeof (type) == "undefined") throw new Error();
            typeLoadingStatus = 1;
        }
        catch (e) {
            if (typeLoadingStatus == 1) throw new Error(controltype + "无法加载");
        }
    }
    if (typeLoadingStatus == 2) {
        scriptUrl = Doo.ControlScripts[controltype];
        needLoadScriptUrls.push(scriptUrl);
        needCheckTypes.push(controltype);
        Doo.ControlLoader.loadedType[controltype] = 0; //开始加载某个类型
        Sys.Debug.trace("开始加载类型:" + controltype);
    };
    //Sys.Debug.trace(controltype + "类型加载状态" + typeLoadingStatus);

    if (needLoadScriptUrls.length > 0) {//还有需要加载的脚本
        var v = -1;
        if (asyncSrc) v = asyncSrc.get_asyncver();
        Doo.ControlLoader.waitTypeControl[controltype] = [[elemorid, controltype, props, callback, v, asyncSrc, userContext]];
        Sys.loadScripts(needLoadScriptUrls, Doo.ControlLoader.scriptLoaded, { type: controltype, checkTypes: needCheckTypes, url: scriptUrl });
        return;
    }

    if (typeLoadingStatus == 1) {//已经加载:1.未通过loadScripts加载的 2.通过loadScripts加载且已经执行了Loaded事件的
        var control = $create(type, props, null, null, elemorid);
        control['__scope'] = asyncSrc;
        Doo.ControlLoader.controlCreated(elemorid, control);
        Sys.Debug.trace("控件已加载[直接]:" + elemorid.id);
        if (callback) callback(control, userContext);
        return control;
    }
    else if (typeLoadingStatus == 0) {//正在加载，未执行Loaded事件
        var v = -1;
        if (asyncSrc) v = asyncSrc.get_asyncver();
        Doo.ControlLoader.waitTypeControl[controltype].push([elemorid, controltype, props, callback, v, asyncSrc, userContext]);
    };
}


function $value(elem) {
    return elem.get_value ? elem.get_value() : elem.value;
}